package com.sgq.ui.component;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.wb.swt.SWTResourceManager;

/**
 * <pre>
 * 多选下拉框复合组件基于Text和List组件封装
 * 组件功能：
 * 1.整个组件可以由 Text 和 List 两个部分组成
 * 2.文本框受到鼠标动作的时候，下拉列表出现；
 * 3.可以使用 CTRL 键来进行多选；
 * 4.可以使用鼠标的滑动同时选中一个连续的列表；
 * 5.当该下来列表失去焦点的时候，文本框获得文字；
 * 6.文字表现为多个选中项目的文本的连接，用逗号分开；
 * 7.下拉列表弹出的时候，需要高亮显示已被选中的文本。
 * </pre>
 * @author gq2010
 *
 */
public class MultSelectionCombo extends Composite {
	/**
	 * 显示输入的文本组件
	 */
	Text text = null;
	/**
	 * 下拉框内容
	 */
	String[] items = null;
	/**
	 * 下拉框已选择的内容
	 */
	String[] selectedItems = new String[] {};
	/**
	 * 选中项
	 */
	int[] selection = new int[] {};
	/**
	 * 显示List的浮动Shell
	 */
	Shell floatShell = null;
	/**
	 * 列表项
	 */
	List list = null;

	/**
	 * 
	 * @param parent 父容器
	 * @param items 下拉列表项
	 * @param selection 默认选择项（索引）
	 * @param selectedItems 默认已选择的项
	 * @param style SWT Style
	 */
	public MultSelectionCombo(Composite parent, String[] items, int[] selection, String[] selectedItems, int style) {
		super(parent, style);
		this.selection = selection;
		this.selectedItems = selectedItems;
		this.items = items;
		init();
	}

	/**
	 * 初始化组件
	 */
	private void init() {
		GridLayout layout = new GridLayout(); 
        layout.marginBottom =0; 
        layout.marginTop = 0; 
        layout.marginLeft =0; 
        layout.marginRight = 0; 
        layout.marginWidth = 0; 
        layout.marginHeight = 0; 
		setLayout(layout);
		text = new Text(this, SWT.BORDER | SWT.READ_ONLY);
		text.setBackground(SWTResourceManager.getColor(255, 255, 255));
		GridData gd_text = new GridData(GridData.FILL_BOTH);
		gd_text.heightHint = 22;
		text.setLayoutData(gd_text);
		
		//鼠标点击时初始化FloatShell
		text.addMouseListener(new MouseAdapter() {
			public void mouseDown(MouseEvent event) {
				super.mouseDown(event);
				initFloatShell();
			}
		});
	}

	/**
	 * 初始化List所在的Shell
	 */
	private void initFloatShell() {
		//获取text的位置，然后设置floatShell的显示位置
		Point p = text.getParent().toDisplay(text.getLocation());
		Point size = text.getSize();
		Rectangle shellRect = new Rectangle(p.x, p.y + size.y, size.x, 0);
		floatShell = new Shell(MultSelectionCombo.this.getShell(), SWT.NO_TRIM);

		GridLayout gl = new GridLayout();
		gl.marginBottom = 2;
		gl.marginTop = 0;
		gl.marginRight = 0;
		gl.marginLeft = 0;
		gl.marginWidth = 0;
		gl.marginHeight = 0;
		floatShell.setLayout(gl);

		floatShell.setSize(shellRect.width, 120);
		floatShell.setLocation(shellRect.x, shellRect.y);
		
		floatShell.addShellListener(new ShellAdapter() {
			public void shellDeactivated(ShellEvent arg0) {
				if (floatShell != null && !floatShell.isDisposed()) {
					selection = list.getSelectionIndices();
					displayText();
					floatShell.dispose();
				}
			}
		});
		
		list = new List(floatShell, SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
		GridData gd = new GridData(GridData.FILL_BOTH);
		list.setLayoutData(gd);
		
		for (String value : items) {
			list.add(value);
		}
		if (null != selection && selection.length != 0) {
			list.setSelection(selection);
		}
		if (null != selectedItems && selectedItems.length != 0) {
			list.setSelection(selectedItems);
		}
		list.addMouseListener(new MouseAdapter() {
			public void mouseUp(MouseEvent event) {
				super.mouseUp(event);
				selection = list.getSelectionIndices();
				if ((event.stateMask & SWT.CTRL) == 0) {
					floatShell.dispose();
					displayText();
				}
			}
		});

		floatShell.open();
	}

	/**
	 * 设置text显示内容
	 */
	private void displayText() {
		if (selection != null && selection.length > 0) {
			StringBuffer sb = new StringBuffer();
			for (int i = 0; i < selection.length; i++) {
				if (i > 0) {
					sb.append(",");
				}
				sb.append(items[selection[i]]);
			}
			text.setText(sb.toString());
		} else {
			text.setText("");
		}
	}

	@Override
	protected void checkSubclass() {}

	public String getText() {
		return text.getText();
	}

	public void setText(String textStr) {
		text.setText(textStr);
		this.selectedItems = textStr.split(",");
	}
}
